{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Introduction\n",
    "\n",
    "This notebook shows how to load and evaluate the MNIST and CIFAR-10 models synthesized and trained as described in the following paper:\n",
    "\n",
    "M.Sinn, M.Wistuba, B.Buesser, M.-I.Nicolae, M.N.Tran: **Evolutionary Search for Adversarially Robust Neural Network** *ICLR SafeML Workshop 2019 (arXiv link to the paper will be added shortly)*.\n",
    "\n",
    "The models were saved in `.h5` using Python 3.6, TensorFlow 1.11.0, Keras 2.2.4."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "from keras.datasets import mnist, cifar10\n",
    "from keras.models import load_model\n",
    "from keras.utils.np_utils import to_categorical\n",
    "import numpy as np\n",
    "\n",
    "from art.config import ART_DATA_PATH\n",
    "from art.classifiers import KerasClassifier\n",
    "from art.attacks import ProjectedGradientDescent\n",
    "from art.utils import get_file"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## MNIST\n",
    "\n",
    "Three different MNIST models are available. Use the following URLs to access them:\n",
    "- `mnist_ratio=0.h5`: trained on 100% benign samples (https://www.dropbox.com/s/bv1xwjaf1ov4u7y/mnist_ratio%3D0.h5?dl=1)\n",
    "- `mnist_ratio=0.5.h5`: trained on 50% benign and 50% adversarial samples (https://www.dropbox.com/s/0skvoxjd6klvti3/mnist_ratio%3D0.5.h5?dl=1)\n",
    "- `mnist_ratio=1.h5`: trained on 100% adversarial samples (https://www.dropbox.com/s/oa2kowq7kgaxh1o/mnist_ratio%3D1.h5?dl=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Load data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "(X_train, y_train), (X_test, y_test) = mnist.load_data()\n",
    "X_train = X_train.reshape(X_train.shape[0], 28, 28, 1).astype('float32') / 255\n",
    "X_test = X_test.reshape(X_test.shape[0], 28, 28, 1).astype('float32') / 255\n",
    "y_train = to_categorical(y_train, 10)\n",
    "y_test = to_categorical(y_test, 10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "E.g. load the model trained on 50% benign and 50% adversarial samples:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "path = get_file('mnist_ratio=0.5.h5',extract=False, path=ART_DATA_PATH,\n",
    "                url='https://www.dropbox.com/s/0skvoxjd6klvti3/mnist_ratio%3D0.5.h5?dl=1')\n",
    "model = load_model(path)\n",
    "classifier = KerasClassifier(model=model, use_logits=False, clip_values=[0,1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Assess accuracy on first `n` benign test samples:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy on first 10000 benign test samples: 0.995100\n"
     ]
    }
   ],
   "source": [
    "n = 10000\n",
    "y_pred = classifier.predict(X_test[:n])\n",
    "accuracy = np.mean(np.argmax(y_pred, axis=1) == np.argmax(y_test[:n], axis=1))\n",
    "print(\"Accuracy on first %i benign test samples: %f\" % (n, accuracy))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define adversarial attack:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "attack = ProjectedGradientDescent(classifier, eps=0.3, eps_step=0.01, max_iter=40, targeted=False, \n",
    "                                  num_random_init=True) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Assess accuracy on first `n` adversarial test samples:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy on first 10 adversarial test samples: 1.000000\n"
     ]
    }
   ],
   "source": [
    "n = 10\n",
    "X_test_adv = attack.generate(X_test[:n], y=y_test[:n])\n",
    "y_adv_pred = classifier.predict(X_test_adv)\n",
    "accuracy = np.mean(np.argmax(y_adv_pred, axis=1) == np.argmax(y_test[:n], axis=1))\n",
    "print(\"Accuracy on first %i adversarial test samples: %f\" % (n, accuracy))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CIFAR-10\n",
    "\n",
    "Similarly to MNIST, three different CIFAR-10 models are available at the following URLs:\n",
    "- `cifar-10_ratio=0.h5`: trained on 100% benign samples (https://www.dropbox.com/s/hbvua7ynhvara12/cifar-10_ratio%3D0.h5?dl=1)\n",
    "- `cifar-10_ratio=0.5.h5`: trained on 50% benign and 50% adversarial samples (https://www.dropbox.com/s/96yv0r2gqzockmw/cifar-10_ratio%3D0.5.h5?dl=1)\n",
    "- `cifar-10_ratio=1.h5`: trained on 100% adversarial samples (https://www.dropbox.com/s/7btc2sq7syf68at/cifar-10_ratio%3D1.h5?dl=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Load data:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "(X_train, y_train), (X_test, y_test) = cifar10.load_data()\n",
    "X_train = X_train.reshape(X_train.shape[0], 32, 32, 3).astype('float32')\n",
    "X_test = X_test.reshape(X_test.shape[0], 32, 32, 3).astype('float32')\n",
    "y_train = to_categorical(y_train, 10)\n",
    "y_test = to_categorical(y_test, 10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "E.g. load the model trained on 50% benign and 50% adversarial samples:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "path = get_file('cifar-10_ratio=0.5.h5',extract=False, path=ART_DATA_PATH,\n",
    "                url='https://www.dropbox.com/s/96yv0r2gqzockmw/cifar-10_ratio%3D0.5.h5?dl=1')\n",
    "model = load_model(path)\n",
    "classifier = KerasClassifier(model=model, use_logits=False, clip_values=[0,255])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Assess accuracy on first `n` benign test samples:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy on first 100 benign test samples: 0.940000\n"
     ]
    }
   ],
   "source": [
    "n = 100\n",
    "y_pred = classifier.predict(X_test[:n])\n",
    "accuracy = np.mean(np.argmax(y_pred, axis=1) == np.argmax(y_test[:n], axis=1))\n",
    "print(\"Accuracy on first %i benign test samples: %f\" % (n, accuracy))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define adversarial attack:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "attack = ProjectedGradientDescent(classifier, eps=8, eps_step=2, max_iter=10, targeted=False, \n",
    "                                  num_random_init=True) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Assess accuracy on first `n` adversarial test samples:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy on first 100 adversarial test samples: 0.450000\n"
     ]
    }
   ],
   "source": [
    "n = 100\n",
    "X_test_adv = attack.generate(X_test[:n], y=y_test[:n])\n",
    "y_adv_pred = classifier.predict(X_test_adv)\n",
    "accuracy = np.mean(np.argmax(y_adv_pred, axis=1) == np.argmax(y_test[:n], axis=1))\n",
    "print(\"Accuracy on first %i adversarial test samples: %f\" % (n, accuracy))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "venv36",
   "language": "python",
   "name": "venv36"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
